선언적 트랜잭션과 트랜잭션 전파 속성

스프링은 트랜잭션 전파 속성을 선언적으로 적용할 수 있는 기능을 제공한다.
AOP를 이용해 코드 외부에서 트랜잭션의 기능을 부여해주고 속성을 지정할 수 있게 하는 방법을 선언적 트랜잭션이라고 한다.
반대로 TransactionTemplate이나 개별 데이터 기술의 트랜잭션 API를 사용해 직접 코드 안에서 사용하는 방법은 프로그램에 의한 트랜잭션이라고 한다.
스프링은 두가지 모두 지원한다.

트랜잭션 동기화와 테스트

트랜잭션 매니저와 트랜잭션 동기화

트랜잭션 추상화 기술의 핵심은 트랜잭션 매니저와 트랜잭션 동기화이다.

트랜잭션 동기화? 진행 중인 트랜잭션이 있는지 확인하고, 트랜잭션 전파 속성에 따라서 이에 참여할 수 있도록 만들어주는 것도 트랜잭션 동기화 기술 덕분이다.

테스트에서는 트랜잭션 매니저를 이용해 트랜잭션에 참여하거나 트랜잭션을 제어하는 방법을 사용할 수도 있다. 스프링의 테스트 컨텍스트를 이용한 테스트에서는 @Autowired를 이용해 애플리케이션 컨텍스트에 등록된 빈을 가져와 테스트 목적으로 활용할 수 있었다. 당연히, 트랜잭션 매니저 빈도 가져올 수 있다.

아래는 3개의 트랜잭션이 만들어진 것을 알 수 있다.

```java

@Test
public void transactionSync(){
    userService.deleteAll();

    userService.add(users.get(0));
    userService.add(users.get(1));

}

```

트랜잭션 매니저를 이용한 테스트용 트랜잭션 제어

테스트 메소드에서 만들어지는 세 개의 트랜잭션을 하나로 통합할 수는 없을까?

테스트에서 트랜잭션 매니저를 이용해 트랜잭션을 시작시키고 이를 동기화해주면 된다.

트랜잭션 동기화 검증

정말 세 개의 메소드가 테스트 코드 내에서 시작된 트랜잭션에 참여하고 있는지 알아보자.

롤백 테스트

롤백 테스트는 - DB 작업이 포함된 테스트가 수행돼도 DB에 영향을 주지 않기 때문에 장점이 많다.
- 여러 개발자가 하나의 공용 테스트용 DB를 사용할 수 있게 도와준다.

하지만 DB 트랜잭션 처리 방법에 따라 롤백이 커밋보다 더 많은 부하를 주는 경우도 있으니 단지 성능 때문에 롤백 테스트가 낫다고는 볼 수 없다.

테스트를 위한 트랜잭션 어노테이션

@Transactional을 포함한, 스프링 컨텍스트 테스트에서 유용하게 쓰이는 애노테이션은 무엇이 있을까?

@Transactional

테스트에도 @Transactional을 적용할 수 있다. 테스트 메소드에 트랜잭션 경계가 자동으로 설정되는 것이다. 메소드 뿐만 아니라, 테스트 클래스 레벨에도 부여할 수 있다. 그러면 테스트 클래스 내의 모든 메소드에 트랜잭션이 적용된다.

@Rollback

테스트 메소드나 클래스에 사용하는 @Transactional은 애플리케이션의 클래스에 적용할 때와 디폴트 속성은 동일하다. 하지만, 테스트용 트랜잭션은 테스트가 끝나면 자동으로 롤백된다.

자동으로 롤백되는 기능을 제어하려면, 별도의 애노테이션을 사용해야 한다. @Rollback은 롤백 여부를 지정하는 값을 갖고 있다. 기본값은 true이다.

@TransactionConfiguration

@Transactional은 테스트 클래스에 넣어서 모든 테스트 메소드에 일괄 적용할 수 있지만, @Rollback 애노테이션은 메소드 레벨에만 적용할 수 있다.

테스트 클래스의 모든 메소드에 트랜잭션을 적용하면서 모든 트랜잭션이 롤백하지 않고 커밋되게 하려면 어떻게 해야 할까?

클래스 레벨에 부여하는 @TrnasactionConfiguration 애노테이션을 이용하면 편리하다.

하지만. 더이상 사용되지 않는다.

NotTransactional과 Propagation.NEVER

굳이 트랜잭션이 필요없는 메소드는 @NotTransactional을 테스트 메소드에 부여하면 클래스 레벨에 부여된 @Transactional설정을 무시할 수 있다. 근데 제거대상이 됐다?

그러므로 @Transactional(propagation=Propagation.NEVER)을 사용하자.

효과적인 DB 테스트

테스트 내에서 트랜잭션을 제어할 수 있는 네 가지 애노테이션을 잘 활용하면 DB가 사용되는 통합 테스트를 만들 때 매우 편리하다.